﻿#define DEBUG

using System.Collections.Generic;
using System.Collections;
using System.Windows;
using System.Diagnostics;
using System;
using System.Windows.Controls;
using System.Reflection;

// todo prompt user where to save file when clicking join
// TODO if ogv files aren't theora encoded
// TODO: Show length, framerate information, etc in listbox (or better yet, listview)

// todo new dialog after join... fail, success? play, open folder, close    
// todo change listbox to listview
// information on joined file (before joining) such as duration, num of files, filesize

//-----------------------------------------------------
// LOW PRIORITY
//-----------------------------------------------------
// drag and drop
// play in vlc? or default player? play joined file in vlc?
// get icons for buttons
// possible bugs - files with same names, but different locations

namespace TheoraJoiner
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private List<string> filelist;
        public string embeddedFilename;
        public MainWindow()
        {
            InitializeComponent();
            JoinButton.IsEnabled = false;
            UpButton.Content = '▲';
            filelist = new List<string>();
            //label1.Content = System.Reflection.Assembly.GetExecutingAssembly().Location;
            
        }

        private void ExtractEmbedded()
        {
        //======================================================
        //Recreate all executable resources
        //======================================================
        
            // Get Current Assembly refrence
            Assembly currentAssembly = Assembly.GetExecutingAssembly();
            // Get all embedded resources
            string[] arrResources = currentAssembly.GetManifestResourceNames();
            embeddedFilename = arrResources[2];

            currentAssembly.GetManifestResourceStream(embeddedFilename);
            
            label1.Content = embeddedFilename;
                               
            System.IO.FileInfo fileInfoOutputFile = new System.IO.FileInfo(embeddedFilename);
            
            if (fileInfoOutputFile.Exists) {
                //overwrite if desired  (depending on your needs)
                fileInfoOutputFile.Delete();
            }
            //OPEN NEWLY CREATING FILE FOR WRITTING
            System.IO.FileStream streamToOutputFile = fileInfoOutputFile.OpenWrite();
            //GET THE STREAM TO THE RESOURCES
            System.IO.Stream streamToResourceFile =
                                currentAssembly.GetManifestResourceStream(embeddedFilename);

            //---------------------------------
            //SAVE TO DISK OPERATION
            //---------------------------------
            const int size = 4096;
            byte[] bytes = new byte[4096];
            int numBytes;
            while ((numBytes = streamToResourceFile.Read(bytes, 0, size)) > 0) {
                streamToOutputFile.Write(bytes, 0, numBytes);
            }

            streamToOutputFile.Close();
            streamToResourceFile.Close();
        }//end_mRecreateAllExecutableResources
        



        private void OpenButton_Click(object sender, RoutedEventArgs e)
        {
            OpenFiles();
        }


        private void OpenFiles()
        {
            Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog();
            openFileDialog.Filter = "Theora videos (.ogv, .ogg)|*.ogv;*.ogg|All files|*.*";
            openFileDialog.Multiselect = true;
            openFileDialog.ShowDialog();

            InsertIntoCollection(openFileDialog.FileNames);
            LoadListbox(openFileDialog.FileNames);
            if (filelist.Count > 1)
                JoinButton.IsEnabled = true;
        }

        private void LoadListbox(string[] files)
        {
            foreach (string s in files)
            {

                System.Windows.Controls.ListBoxItem listBoxItem = new System.Windows.Controls.ListBoxItem();
                listBoxItem.Content = System.IO.Path.GetFileName(s);
                listBox1.Items.Add(listBoxItem);

                // listBox1.Items.Add(System.IO.Path.GetFileName(s));  // doesn't work right
            }
        }

        private void InsertIntoCollection(string[] files)
        {
            filelist.AddRange(files);
        }

        private void JoinButton_Click(object sender, RoutedEventArgs e)
        {
            if (listBox1.Items.IsEmpty == false)
                JoinFiles();
            else
            {
                JoinButton.IsEnabled = false;
            }
        }

        private void JoinFiles()
        {
            ExtractEmbedded();
            //ProcessStartInfo processInfo = new ProcessStartInfo(@"C:\oggCat.exe");
            ProcessStartInfo processInfo = new ProcessStartInfo(embeddedFilename);
            processInfo.RedirectStandardOutput = true;
            processInfo.RedirectStandardError = true;
            processInfo.RedirectStandardInput = true;
            processInfo.UseShellExecute = false;
            processInfo.CreateNoWindow = true;
            string arguments = "";
            string outputFile = "joinedVideo.ogv";
            //Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + System.IO.Path.DirectorySeparatorChar + "joinedVideo.ogv";

            
            foreach (string s in filelist)
            {
                arguments += @"""" + s + @""" ";
            }
            processInfo.Arguments = outputFile + " " + arguments;
            processInfo.FileName = processInfo.FileName;
            processInfo.WorkingDirectory = @"C:\";

            Process p = Process.Start(processInfo);

#if DEBUG
            System.IO.StreamReader sr2 = p.StandardOutput;
            System.IO.StreamReader sr3 = p.StandardError;
            using (System.IO.StreamWriter sw = new System.IO.StreamWriter(@"c:\TestFile.txt"))
            {
                // Add some text to the file.

                sw.Write(sr2.ReadToEnd());
                sw.Write(sr3.ReadToEnd());

            }
#endif
            OpenOutputFolder();
        }

        private void OpenOutputFolder()
        {
            string outputPath = @"c:\joinedVideo.ogv";
            string argument = @"/select, " + outputPath;
            System.Diagnostics.Process.Start("explorer.exe", argument);

        }

        private void OpenMenuItem_Click(object sender, RoutedEventArgs e)
        {
            OpenFiles();
        }

        private void MenuItemAdd_Click(object sender, RoutedEventArgs e)
        {
            OpenFiles();
        }

        private void MenuItemRemove_Click(object sender, RoutedEventArgs e)
        {
            RemoveSelected();
        }

        private void RemoveSelected()
        {
            // lengthy code back when the program allowed multi-selection
            ArrayList l = new ArrayList(listBox1.SelectedItems);
            foreach (System.Windows.Controls.ListBoxItem item in l)
            {
                listBox1.Items.Remove(item);

                int index = filelist.FindIndex(delegate(string fileItem)
                        {
                            return fileItem.Contains(item.Content.ToString());
                        });
                filelist.RemoveAt(index);
            }

            if (filelist.Count < 2)
                JoinButton.IsEnabled = false;

        }

        private void RemoveButton_Click(object sender, RoutedEventArgs e)
        {
            RemoveSelected();
        }

        private void RemoveMenuItem_Click(object sender, RoutedEventArgs e)
        {
            RemoveSelected();
        }

        private void ExitMenuItem_Click(object sender, RoutedEventArgs e)
        {
            Application.Current.Shutdown();
        }

        private void RemoveAllButton_Click(object sender, RoutedEventArgs e)
        {
            listBox1.Items.Clear();
            filelist.Clear();
            JoinButton.IsEnabled = false;
        }

        private void JoinMenuItem_Click(object sender, RoutedEventArgs e)
        {
            JoinFiles();
        }

        private void listBox1_SelectionChanged_1(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            foreach (System.Windows.Controls.ListBoxItem item in e.AddedItems)
                label1.Content = item.ToString() + " " + listBox1.SelectedIndex ;

            /*
            foreach (string s in e.AddedItems.)
                label1.Content = s + listBox1.SelectedIndex;
            foreach (string s in e.RemovedItems)
                label2.Content = s + listBox1.SelectedIndex;
            Console.WriteLine("test"); Console.Read();
             */
        }

        private void UpButton_Click(object sender, RoutedEventArgs e)
        {
            int index = listBox1.SelectedIndex;
            if (index > 0)  // not -1 nor at the top of the list
            {
                if (listBox1.Items.Count > 1)
                {
                    //selected to be moved up
                    ListBoxItem tmp = new ListBoxItem();
                    tmp.Content = ((ListBoxItem)listBox1.Items.GetItemAt(index)).Content;

                    // to be moved down
                    ListBoxItem tmp2 = new ListBoxItem();
                    tmp2.Content = ((ListBoxItem)listBox1.Items.GetItemAt(index - 1)).Content;

                    listBox1.Items.RemoveAt(index - 1);

                    listBox1.Items.RemoveAt(index - 1);
                    listBox1.Items.Insert(index - 1, tmp);
                    listBox1.Items.Insert(index, tmp2);
                    listBox1.SelectedIndex = index - 1;
                }

            }
        }

        private void DownButton_Click(object sender, RoutedEventArgs e)
        {
            int index = listBox1.SelectedIndex;
            if (index != listBox1.Items.Count-1 && index != -1)
            {
                if (listBox1.Items.Count > 1)
                {
                    //selected to be moved down (+1 index)
                    ListBoxItem tmp = new ListBoxItem();
                    tmp.Content = ((ListBoxItem)listBox1.Items.GetItemAt(index)).Content;

                    // to be moved down (-1 index)
                    ListBoxItem tmp2 = new ListBoxItem();
                    tmp2.Content = ((ListBoxItem)listBox1.Items.GetItemAt(index + 1)).Content;

                    listBox1.Items.RemoveAt(index + 1);

                    listBox1.Items.RemoveAt(index);
                    listBox1.Items.Insert(index, tmp2);
                    listBox1.Items.Insert(index +1, tmp);
                    listBox1.SelectedIndex = index +1;
                }
            }
        }

        private void AboutMenu_Click(object sender, RoutedEventArgs e)
        {
            Window2 aboutWindow = new Window2();
            aboutWindow.ShowDialog();
        }

    }
}
